load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library")
load("@com_google_googleapis_imports//:imports.bzl", "cc_proto_library")
load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test")

package(
    default_visibility = ["//visibility:public"],
    licenses = ["notice"],
)

proto_library(
    name = "fuzzer_proto",
    srcs = ["fuzzer.proto"],
    deps = [
        "//p4_pdpi:ir_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_proto",
    ],
)

cc_proto_library(
    name = "fuzzer_cc_proto",
    deps = [":fuzzer_proto"],
)

cc_library(
    name = "switch_state",
    srcs = ["switch_state.cc"],
    hdrs = ["switch_state.h"],
    deps = [
        "//gutil/gutil:collections",
        "//gutil/gutil:proto",
        "//gutil/gutil:status",
        "//p4_pdpi:built_ins",
        "//p4_pdpi:entity_keys",
        "//p4_pdpi:ir",
        "//p4_pdpi:ir_cc_proto",
        "//p4_pdpi:translation_options",
        "//p4_pdpi/internal:ordered_map",
        "@com_github_google_glog//:glog",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/container:btree",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/status:statusor",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/strings:str_format",
        "@com_google_absl//absl/types:optional",
        "@com_google_absl//absl/types:span",
        "@com_google_protobuf//:protobuf",
    ],
)

cc_test(
    name = "switch_state_test",
    srcs = ["switch_state_test.cc"],
    deps = [
        ":switch_state",
        "//gutil/gutil:collections",
        "//gutil/gutil:proto_matchers",
        "//gutil/gutil:status",
        "//gutil/gutil:status_matchers",
        "//gutil/gutil:testing",
        "//p4_pdpi:ir",
        "//p4_pdpi:ir_cc_proto",
        "//p4_pdpi:pd",
        "//p4_pdpi/testing:main_p4_pd_cc_proto",
        "//p4_pdpi/testing:test_p4info_cc",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/status:statusor",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/types:span",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_library(
    name = "fuzzer_config",
    srcs = [
        "fuzzer_config.cc",
    ],
    hdrs = [
        "fuzzer_config.h",
    ],
    deps = [
        ":fuzzer_cc_proto",
        ":switch_state",
        "//gutil/gutil:proto",
        "//gutil/gutil:status",
        "//lib/p4rt:p4rt_port",
        "//p4_pdpi:ir",
        "//p4_pdpi:ir_cc_proto",
        "//p4_pdpi:ir_properties",
        "//p4_pdpi:reference_annotations",
        "@com_github_google_glog//:glog",
        "@com_github_p4lang_p4_constraints//p4_constraints:ast",
        "@com_github_p4lang_p4_constraints//p4_constraints/backend:constraint_info",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/container:btree",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/status:statusor",
        "@com_google_absl//absl/strings",
        "@com_google_protobuf//:protobuf",
    ],
)

cc_test(
    name = "fuzzer_config_test",
    srcs = ["fuzzer_config_test.cc"],
    deps = [
        ":fuzzer_config",
        "//gutil/gutil:status_matchers",
        "//p4_pdpi:ir",
        "//p4_pdpi:ir_cc_proto",
        "@com_github_p4lang_p4_constraints//gutils:parse_text_proto",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_google_absl//absl/status",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_library(
    name = "mutation_and_fuzz_util",
    srcs = [
        "constraints.cc",
        "fuzz_util.cc",
        "mutation.cc",
    ],
    hdrs = [
        "constraints.h",
        "fuzz_util.h",
        "mutation.h",
    ],
    deps = [
        ":annotation_util",
        ":fuzzer_cc_proto",
        ":fuzzer_config",
        ":switch_state",
        "//gutil/gutil:collections",
        "//gutil/gutil:proto",
        "//gutil/gutil:status",
        "//lib/p4rt:p4rt_port",
        "//p4_pdpi:built_ins",
        "//p4_pdpi:entity_keys",
        "//p4_pdpi:ir_cc_proto",
        "//p4_pdpi:ir_properties",
        "//p4_pdpi:references",
        "//p4_pdpi/internal:ordered_map",
        "//p4_pdpi/netaddr:ipv6_address",
        "//p4_pdpi/string_encodings:byte_string",
        "//p4_pdpi/utils:ir",
        "@com_github_google_glog//:glog",
        "@com_github_p4lang_p4_constraints//p4_constraints:ast",
        "@com_github_p4lang_p4_constraints//p4_constraints:ast_cc_proto",
        "@com_github_p4lang_p4_constraints//p4_constraints:constraint_source",
        "@com_github_p4lang_p4_constraints//p4_constraints/backend:constraint_info",
        "@com_github_p4lang_p4_constraints//p4_constraints/backend:symbolic_interpreter",
        "@com_github_p4lang_p4_constraints//p4_constraints/frontend:constraint_kind",
        "@com_github_p4lang_p4_constraints//p4_constraints/frontend:parser",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_github_p4lang_p4runtime//:p4types_cc_proto",
        "@com_google_absl//absl/algorithm:container",
        "@com_google_absl//absl/base",
        "@com_google_absl//absl/base:endian",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/random",
        "@com_google_absl//absl/random:distributions",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/status:statusor",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/types:optional",
        "@com_google_absl//absl/types:span",
        "@com_google_protobuf//:protobuf",
    ],
)

cc_test(
    name = "fuzz_util_test",
    size = "large",
    timeout = "long",
    srcs = [
        "fuzz_util_test.cc",
    ],
    data = ["acl_table_test.p4info.pb.txt"],
    deps = [
        ":fuzzer_cc_proto",
        ":fuzzer_config",
        ":mutation_and_fuzz_util",
        ":test_utils",
        "//gutil/gutil:collections",
        "//gutil/gutil:proto_matchers",
        "//gutil/gutil:status_matchers",
        "//gutil/gutil:testing",
        "//p4_pdpi:built_ins",
        "//p4_pdpi:ir_cc_proto",
        "@com_github_google_glog//:glog",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/container:flat_hash_set",
        "@com_google_absl//absl/random",
        "@com_google_absl//absl/random:distributions",
        "@com_google_absl//absl/random:seed_sequences",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/status:statusor",
        "@com_google_absl//absl/strings",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_library(
    name = "annotation_util",
    srcs = ["annotation_util.cc"],
    hdrs = ["annotation_util.h"],
    deps = [
        ":fuzzer_cc_proto",
        "//gutil/gutil:status",
        "//p4_pdpi:ir",
        "//p4_pdpi:ir_cc_proto",
        "//p4_pdpi/utils:ir",
        "//thinkit:test_environment",
        "@com_github_google_glog//:glog",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/strings",
    ],
)

cc_library(
    name = "oracle_util",
    srcs = [
        "oracle_util.cc",
    ],
    hdrs = ["oracle_util.h"],
    deps = [
        ":fuzzer_cc_proto",
        ":switch_state",
        "//gutil/gutil:status",
        "//p4_pdpi:entity_keys",
        "//p4_pdpi:ir",
        "//p4_pdpi:ir_cc_proto",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/algorithm:container",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/types:optional",
        "@com_google_absl//absl/types:span",
    ],
)

cc_test(
    name = "oracle_util_test",
    srcs = ["oracle_util_test.cc"],
    deps = [
        ":fuzzer_cc_proto",
        ":mutation_and_fuzz_util",
        ":oracle_util",
        ":switch_state",
        ":test_utils",
        "//gutil/gutil:status",
        "//gutil/gutil:status_matchers",
        "//gutil/gutil:testing",
        "//p4_pdpi:ir",
        "//p4_pdpi:ir_cc_proto",
        "//p4_pdpi/netaddr:ipv4_address",
        "//sai_p4/instantiations/google:instantiations",
        "//sai_p4/instantiations/google:sai_p4info_cc",
        "//sai_p4/instantiations/google:sai_pd_cc_proto",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/status:statusor",
        "@com_google_absl//absl/strings",
        "@com_google_googleapis//google/rpc:code_cc_proto",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_library(
    name = "test_utils",
    testonly = True,
    srcs = ["test_utils.cc"],
    hdrs = ["test_utils.h"],
    deps = [
        ":fuzzer_config",
        ":switch_state",
        "//lib/p4rt:p4rt_port",
        "//p4_pdpi:ir_cc_proto",
        "//p4_pdpi/internal:ordered_map",
        "//p4_pdpi/testing:test_p4info_cc",
        "//sai_p4/instantiations/google:sai_p4info_cc",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/random",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/status:statusor",
        "@com_google_absl//absl/strings",
    ],
)

cc_test(
    name = "constraints_test",
    srcs = ["constraints_test.cc"],
    deps = [
        ":fuzzer_config",
        ":mutation_and_fuzz_util",
        ":switch_state",
        ":test_utils",
        "//gutil/gutil:collections",
        "//gutil/gutil:status",
        "//gutil/gutil:status_matchers",
        "//gutil/gutil:testing",
        "//p4_pdpi:ir",
        "//p4_pdpi:ir_cc_proto",
        "@com_github_google_glog//:glog",
        "@com_github_p4lang_p4_constraints//p4_constraints:ast_cc_proto",
        "@com_github_p4lang_p4_constraints//p4_constraints/backend:constraint_info",
        "@com_github_p4lang_p4_constraints//p4_constraints/backend:interpreter",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/random",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/strings",
        "@com_google_googletest//:gtest_main",
    ],
)

# -- P4 libraries for testing -------------------------------------------------

p4_library(
    name = "single_table_single_entry",
    src = "p4_programs/single_table_single_entry.p4",
    p4info_out = "single_table_single_entry.p4info.pb.txt",
)

p4_library(
    name = "constraints_equals",
    src = "p4_programs/constraints_equals.p4",
    p4info_out = "constraints_equals.p4info.pb.txt",
)

p4_library(
    name = "constraints_not_equals",
    src = "p4_programs/constraints_not_equals.p4",
    p4info_out = "constraints_not_equals.p4info.pb.txt",
)

p4_library(
    name = "acl_table_test",
    src = "p4_programs/acl_table_test.p4",
    p4info_out = "acl_table_test.p4info.pb.txt",
    deps = [
        "p4_programs/sai-p4-google/acl_actions.p4",
        "p4_programs/sai-p4-google/acl_set_vrf.p4",
        "p4_programs/sai-p4-google/headers.p4",
        "p4_programs/sai-p4-google/ids.h",
        "p4_programs/sai-p4-google/metadata.p4",
        "p4_programs/sai-p4-google/resource_limits.p4",
    ],
)

p4_library(
    name = "sai_main",
    src = "p4_programs/sai-p4-google/sai_main.p4",
    p4info_out = "sai_main_info.pb.txt",
    deps = glob(["p4_programs/sai-p4-google/*"]),
)

cc_library(
    name = "acl_table_test_ids",
    hdrs = ["p4_programs/sai-p4-google/ids.h"],
)

# go/golden-test-with-coverage
cc_test(
    name = "switch_state_assert_entry_equality_test_runner",
    srcs = ["switch_state_assert_entry_equality_test_runner.cc"],
    linkstatic = True,
    deps = [
        ":switch_state",
        "//gutil/gutil:collections",
        "//gutil/gutil:proto",
        "//gutil/gutil:status",
        "//gutil/gutil:testing",
        "//p4_pdpi:ir",
        "//p4_pdpi:ir_cc_proto",
        "//p4_pdpi/testing:test_p4info_cc",
        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
        "@com_google_absl//absl/status",
        "@com_google_absl//absl/status:statusor",
        "@com_google_absl//absl/strings",
        "@com_google_absl//absl/types:span",
        "@com_google_protobuf//:protobuf",
    ],
)

cmd_diff_test(
    name = "switch_state_assert_entry_equality_test",
    actual_cmd = "$(execpath :switch_state_assert_entry_equality_test_runner)",
    expected = ":switch_state_assert_entry_equality_test.expected.output",
    tools = [":switch_state_assert_entry_equality_test_runner"],
)
